import { Component, ElementRef, EventEmitter, forwardRef, Input, OnInit, Output, ViewChild } from '@angular/core';
import { CdkConnectedOverlay, CdkOverlayOrigin, ConnectedOverlayPositionChange } from '@angular/cdk/overlay';
import { Platform } from '@angular/cdk/platform';
import { reqAnimFrame } from 'ng-zorro-antd/core/polyfill';
import { ESCAPE } from '@angular/cdk/keycodes';
import { slideMotion } from 'ng-zorro-antd/core/animation';
import { OnChangeType, OnTouchedType } from 'ng-zorro-antd/core/types';
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';

@Component({
	selector: 'nz-cron',
	templateUrl: './nz-cron.component.html',
	styleUrls: ['./nz-cron.component.less'],
	animations: [slideMotion],
	providers: [
		{
			provide: NG_VALUE_ACCESSOR,
			useExisting: forwardRef(() => NzCronComponent),
			multi: true
		}
	],
	host: {
		'[class.ant-select]': `true`,
		'[class.ant-select-show-arrow]': `true`,
		'[class.ant-select-allow-clear]': 'true',
		'[class.ant-select-borderless]': 'nzBorderless',
		'[class.ant-select-open]': 'nzOpen',
		'[class.ant-select-focused]': 'nzOpen || focused',
		'[class.ant-select-single]': `true`,
		'[class.ant-select-rtl]': `dir === 'rtl'`,
		'(click)': 'onHostClick()'
	}

})
export class NzCronComponent implements ControlValueAccessor, OnInit {
	@ViewChild(CdkOverlayOrigin, { static: true, read: ElementRef }) originElement!: ElementRef;
	@ViewChild(CdkConnectedOverlay, { static: true }) cdkConnectedOverlay!: CdkConnectedOverlay;
	@Input() nzBackdrop = true;
	@Input() nzDropdownMatchSelectWidth = false;
	@Input() nzDropdownClassName: string | null = null;
	@Input() nzOpen = false;
	@Output() readonly nzOpenChange = new EventEmitter<boolean>();
	@Input() nzShowSearch = false;
	@Input() nzDisabled = false;
	@Input() nzPlaceholder = '请选择';

	onChange: OnChangeType = () => { };
	onTouched: OnTouchedType = () => { };
	dropDownPosition: 'top' | 'center' | 'bottom' = 'bottom';

	triggerWidth: number | null = 600;

	tabList = Array.from(Array(7)).map(_ => '*');
	constructor(
		private platform: Platform,
		private elementRef: ElementRef,
	) { }

	ngOnInit() {
	}

	tabListChange() {
		setTimeout(() => {
			this.onChange(this.tabList.join(' '))
		});
	}
	writeValue(formVal: any): void {
		if (formVal) {
			const res = formVal.split(' ');
			if (res.length) {
				this.tabList = Array.from(Array(7)).map((d, i) => res[i] || '');
				return;
			}
			return;
		}
	}
	registerOnChange(fn: OnChangeType): void {
		this.onChange = fn;
	}

	registerOnTouched(fn: OnTouchedType): void {
		this.onTouched = fn;
	}
	setDisabledState(disabled: boolean): void {
		this.nzDisabled = disabled;
		if (disabled) {
			this.setOpenState(false);
		}
	}




	onPositionChange(position: ConnectedOverlayPositionChange): void {
		this.dropDownPosition = position.connectionPair.originY;
	}

	updateCdkConnectedOverlayStatus(): void {
		if (this.platform.isBrowser && this.originElement.nativeElement) {
			reqAnimFrame(() => {
				this.triggerWidth = this.originElement.nativeElement.getBoundingClientRect().width;
			});
		}
	}

	updateCdkConnectedOverlayPositions(): void {
		reqAnimFrame(() => {
			this.cdkConnectedOverlay?.overlayRef?.updatePosition();
		});
	}

	setOpenState(value: boolean): void {
		if (this.nzOpen !== value) {
			this.nzOpen = value;
			this.nzOpenChange.emit(value);
			this.onOpenChange();
		}
	}


	onOpenChange(): void {
		this.updateCdkConnectedOverlayStatus();
	}

	onOverlayKeyDown(e: KeyboardEvent): void {
		if (e.keyCode === ESCAPE) {
			this.setOpenState(false);
		}
	}
	onClickOutside(event: MouseEvent): void {
		if (!this.elementRef.nativeElement.contains(event.target)) {
			this.setOpenState(false);
		}
	}
	onHostClick(): void {
		if (this.nzOpen && this.nzShowSearch) {
			return;
		}
		this.setOpenState(!this.nzOpen);
	}


	onClearCron(e: MouseEvent) {
		e.preventDefault();
		e.stopPropagation();
	}



}
